package com.michaelbulava.TFS.vcs.internal;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.ModuleDependenciesAnalyzer;
import com.intellij.openapi.vcs.FilePath;
import com.michaelbulava.TFS.Messages;
import com.michaelbulava.TFS.log.FileLogger;
import com.michaelbulava.TFS.persistence.IdeaPersistenceStoreProvider;
import com.michaelbulava.TFS.vcs.TFSVcs;
import com.michaelbulava.TFS.vcs.exceptions.NotConnectedToTFS;
import com.michaelbulava.TFS.vcs.exceptions.TFSException;
import com.michaelbulava.TFS.vcs.utils.TFSFileUtil;
import com.michaelbulava.TFS.vcs.utils.TFSProgressUtil;
import com.microsoft.tfs.core.clients.versioncontrol.Workstation;
import com.microsoft.tfs.core.clients.versioncontrol.path.ItemPath;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.DeletedState;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.ItemType;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace;
import com.microsoft.tfs.core.clients.versioncontrol.workspacecache.WorkspaceInfo;
import com.microsoft.tfs.util.Check;

import java.text.MessageFormat;
import java.util.*;

/**
 * Created by mbulava on 6/9/2015.
 */
public class WorkstationHelper {
    private static final Logger log = FileLogger.getInstance(WorkstationHelper.class);

    public static List<FilePath> processByWorkspaces(Collection<FilePath> localPaths, boolean considerChildMappings,
                                                     Project project, VoidDelegateProcess processor) throws TFSException {
        return processByWorkspaces(localPaths, considerChildMappings, project, null, processor);
    }

    public static List<FilePath> processByWorkspaces(Collection<FilePath> localPaths, boolean considerChildMappings,
                                                    Project project, ProgressIndicator progressIndicator,
                                                    VoidDelegateProcess processor) throws TFSException{
        log.info(String.format("Starting WorkstationHelper.processByWorkspace with %d files.", localPaths.size()));
        List<FilePath> orphanPaths = new ArrayList<FilePath>();
        Map<Workspace, List<FilePath>> workspace2LocalPaths = new HashMap<Workspace, List<FilePath>>();
        TFSProgressUtil.setProgressText(progressIndicator, Messages.getString("WorkstationHelper.MappingFiles"));
        for(FilePath localPath : localPaths){
            TFSProgressUtil.setProgressText2(progressIndicator, Messages.getString("WorkstationHelper.WaitingForWorkspace"));
            Module module = TFSFileUtil.getModuleForFile(localPath, project);
            Check.notNull(module, "module for [" + localPath.getPath()+"] not found.");
            Workspace workspace = TFSVcs.getWorkspaceForModule(module);

            TFSProgressUtil.setProgressText2(progressIndicator, "");
            if (workspace != null){
                List<FilePath> workspaceLocalPaths = workspace2LocalPaths.get(workspace);
                if (workspaceLocalPaths == null){
                    workspaceLocalPaths = new ArrayList<FilePath>();
                    workspace2LocalPaths.put(workspace, workspaceLocalPaths);
                }
                workspaceLocalPaths.add(localPath);
                continue;
            }
            orphanPaths.add(localPath);
        }
        log.info(String.format("WorkstationHelper.processByWorkspace, processed %1$d files for a total of %2$d Workspaces and %3$d orphaned files",
                localPaths.size(), workspace2LocalPaths.keySet().size(), orphanPaths.size()));

        for(Workspace workspace : workspace2LocalPaths.keySet()){
            TFSProgressUtil.setProgressText(progressIndicator, MessageFormat.format(
                    Messages.getString("WorkstationHelper.ExecuteProcess"), new Object[]{ workspace.getDisplayName() }));

            List<FilePath> currentLocalPaths = workspace2LocalPaths.get(workspace);
            log.info(String.format("Executing supplied VoidDelegateProcess for %1$d files on workspace %2%s",
                    currentLocalPaths.size(), workspace.getName()));
            processor.executeRequest(workspace, currentLocalPaths);
        }

        return orphanPaths;
    }

    public interface VoidDelegateProcess{
        void executeRequest(Workspace workspace, List<FilePath> localPaths) throws TFSException;
    }


}
